module BinaryToBCD (
	input	[7:0] Binary_in,
	output	[7:0] Bcd_Out
);
	wire [19:0] shift_reg [0:8];
	assign shift_reg[0] = {12'b0, Binary_in};

	genvar i;
	generate
		for (i = 0; i < 8; i = i + 1) begin : shift_chain
			DoubleDabble stage (
				.in(shift_reg[i]),
				.out(shift_reg[i+1])
			);
		end
	endgenerate

	assign Bcd_Out = shift_reg[8][15:8];
endmodule

module DoubleDabble (
	input	[19:0] in,
	output	[19:0] out
);
	wire [3:0] tens = in[15:12];
	wire [3:0] ones = in[11:8];
	wire [3:0] tens_adj, ones_adj;

	Add3 add_tens (
		.in(tens),
		.out(tens_adj)
	);

	Add3 add_ones (
		.in(ones),
		.out(ones_adj)
	);

	assign out = {tens_adj, ones_adj, in[7:0]} << 1;
endmodule

module Add3 (
	input	[3:0] in,
	output	[3:0] out
);
	wire in3 = in[3];
	wire in2 = in[2];
	wire in1 = in[1];
	wire in0 = in[0];

	assign out[3] = (~in3 & in2 & in1) |
					(~in3 & in2 & in0) |
					( in3 & ~in2)      |
					( in3 & ~in1 & ~in0);

	assign out[2] = ( in3 & ~in2 & in1)  |
					 ( in3 & ~in2 & in0)  |
					 ( in2 & ~in1 & ~in0);

	assign out[1] = (~in3 & ~in2 & in1) |
					 ( in3 & ~in1 & ~in0) |
					 ( in1 & in0);

	assign out[0] = (~in3 & ~in2 & in0) |
					 ( in3 & ~in0)        |
					 ( in2 & in1 & ~in0);
endmodule
